package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.client.VipServiceConfigFeignClient;
import com.atguigu.tingshu.vo.account.AccountDeductVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private AlbumInfoFeignClient albumInfoFeignClient;
    @Resource
    private UserInfoFeignClient userInfoFeignClient;
    @Resource
    private VipServiceConfigFeignClient vipServiceConfigFeignClient;
    @Resource
    private TrackInfoFeignClient trackInfoFeignClient;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private UserAccountFeignClient userAccountFeignClient;
    @Resource
    private RabbitService rabbitService;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private OrderDerateMapper orderDerateMapper;

    /**
     * 下单
     * @param userId
     * @param tradeVo
     * @return
     */
    @Override
    public OrderInfoVo trade(Long userId, TradeVo tradeVo) {
        // 本质上就是给Vo属性赋值
        // 原始金额
        BigDecimal originalAmount = new BigDecimal("0.00");
        // 减免金额
        BigDecimal derateAmount = new BigDecimal("0.00");
        // 实际金额
        BigDecimal orderAmount = new BigDecimal("0.00");
        // 订单明细
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        // 订单减免明细
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();
        // 通过判断区分购买项
        if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(tradeVo.getItemType())) {
            // 专辑购买
            Long albumId = tradeVo.getItemId();
            // 看是否之前买过专辑
            Result<Boolean> paidAlbum = userInfoFeignClient.isPaidAlbum(albumId);
            Assert.notNull(paidAlbum, "远程调用用户服务获取用户数据paidAlbum失败");
            Boolean paidAlbumData = paidAlbum.getData();
            Assert.notNull(paidAlbum.getData(), "远程调用用户服务获取用户数据paidAlbum失败");
            if (paidAlbumData) {
                // 证明之前购买过 就不需要再次购买
                throw new RuntimeException("您已经购买过该专辑，无需重复购买");
            }
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "远程调用专辑服务获取专辑数据失败");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "远程调用专辑服务获取专辑数据albumInfo失败");
            // 赋值原始金额
            originalAmount = albumInfo.getPrice();
            // 折扣金额  针对专辑进行折扣  需要判断用户的身份是不是Vip
            Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfo(userId);
            Assert.notNull(userInfoVoResult, "远程调用用户服务获取用户数据失败");
            UserInfoVo userInfoVo = userInfoVoResult.getData();
            Assert.notNull(userInfoVo, "远程调用用户服务获取用户数据userInfoVo失败");
            // 判断用户是否为VIP
            if (0 == userInfoVo.getIsVip() || (1 == userInfoVo.getIsVip() && userInfoVo.getVipExpireTime().before(new Date()))) {
                // 普通用户
                if (albumInfo.getDiscount().compareTo(new BigDecimal("-1")) != 0) {
                    //说明有折扣；
                    derateAmount = orderAmount.multiply(new BigDecimal("10").subtract(albumInfo.getDiscount()))
                            .divide(new BigDecimal("10"), 2, BigDecimal.ROUND_HALF_UP);
                }
            } else {
                // Vip用户
                if (albumInfo.getVipDiscount().compareTo(new BigDecimal("-1")) != 0) {
                    //说明有折扣；
                    derateAmount = orderAmount.multiply(new BigDecimal("10").subtract(albumInfo.getVipDiscount()))
                            .divide(new BigDecimal("10"), 2, BigDecimal.ROUND_HALF_UP);
                }
            }
            // 实际金额
            orderAmount = originalAmount.subtract(derateAmount);
            // 订单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            // 赋值
            orderDetailVo.setItemId(albumId);
            orderDetailVo.setItemName(albumInfo.getAlbumTitle());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemPrice(albumInfo.getPrice());
            orderDetailVoList.add(orderDetailVo);
            // 减免明细
            OrderDerateVo orderDerateVo = new OrderDerateVo();
            if (derateAmount.compareTo(new BigDecimal("0.00")) != 0) {
                //折扣金额大于0
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                orderDerateVo.setRemarks("专辑折扣");
                orderDerateVoList.add(orderDerateVo);
            }
        }
        else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(tradeVo.getItemType())) {
            // 声音购买 trsckId = itemId ;声音ID trackCount = 购买的集数
            // trackCount == 0 表示购买本集
            if (tradeVo.getTrackCount() < 0) {
                throw new RuntimeException("购买集数不能小于0");
            }
            //购买声音不支持折扣  原价购买
            // 赋值
            // 原始金额==实际金额==单价(albumInfo.getPrice())*数量(trackCount)
            // 订单明细== 每一集声音的明细(价格 标题，图片等相关信息)
            // 减免金额不用赋值  减免明细也不用赋值
            // 通过声音id获取声音信息
            Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(tradeVo.getItemId());
            Assert.notNull(trackInfoResult, "远程调用声音服务获取数据失败");
            TrackInfo trackInfo = trackInfoResult.getData();
            Assert.notNull(trackInfo, "远程调用声音服务获取数据trackInfo失败");
            // 通过声音对象获取专辑信息
            Long albumId = trackInfo.getAlbumId();
            // 获取专辑对象
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "远程调用专辑服务获取数据失败");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "远程调用专辑服务获取数据albumInfo失败");
            // 原始金额==实际金额==单价(albumInfo.getPrice())*数量(trackCount)
//            originalAmount = albumInfo.getPrice().multiply(new BigDecimal(tradeVo.getTrackCount() + 1));
            originalAmount = tradeVo.getTrackCount() == 0 ? albumInfo.getPrice() : albumInfo.getPrice().multiply(new BigDecimal(tradeVo.getTrackCount()));
            // 订单实际金额
            orderAmount = originalAmount;
            // 远程调用
            Result<List<TrackInfo>> trackInfoListResult = trackInfoFeignClient.findPaidTrackInfoList(tradeVo.getItemId(), tradeVo.getTrackCount());
            Assert.notNull(trackInfoListResult, "远程调用声音服务获取数据失败");
            List<TrackInfo> trackInfoList = trackInfoListResult.getData();
            Assert.notNull(trackInfoList, "远程调用声音服务获取数据trackInfoList失败");
            // 循环遍历并对orderDetailVo进行赋值 最后组成一个新的集合
            // 数据返回
            orderDetailVoList = trackInfoList.stream().map(trackInfo1 -> {
                // 展示订单明细 每一集的信息   标题  价格  图片
                OrderDetailVo orderDetailVo = new OrderDetailVo();
                // 赋值 跟购买集数有关
                orderDetailVo.setItemId(trackInfo1.getId());
                orderDetailVo.setItemName(trackInfo1.getTrackTitle());
                orderDetailVo.setItemUrl(trackInfo1.getCoverUrl());
                orderDetailVo.setItemPrice(albumInfo.getPrice());
                return orderDetailVo;
            }).collect(Collectors.toList());

        }
        else {
            //vip 购买
            // itemId = vip_service_config.id
            Long vipServiceConfigId = tradeVo.getItemId();
            // 获取vip服务配置信息vip_service_config
            Result<VipServiceConfig> serviceConfigResult = vipServiceConfigFeignClient.getVipServiceConfig(vipServiceConfigId);
            Assert.notNull(serviceConfigResult, "远程调用vip服务配置服务获取数据失败");
            VipServiceConfig vipServiceConfig = serviceConfigResult.getData();
            Assert.notNull(vipServiceConfig, "远程调用vip服务配置服务获取数据vipServiceConfig失败");
            // 原始金额
            originalAmount = vipServiceConfig.getPrice();
            // 折扣金额
            derateAmount = originalAmount.subtract(vipServiceConfig.getDiscountPrice());
            // 实际金额
            orderAmount = vipServiceConfig.getDiscountPrice();
            //订单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(vipServiceConfigId);
            orderDetailVo.setItemName(vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVoList.add(orderDetailVo);
            // 订单减免
            if (derateAmount.compareTo(new BigDecimal("0.00")) != 0) {
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                orderDerateVo.setRemarks("VIP服务折扣");
                orderDerateVoList.add(orderDerateVo);
            }


        }

        // 创建一个需要返回的对象
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        String tradeNo = UUID.randomUUID().toString().replace("-", "");
        //  需要存储一个tradeNo;
        String tradeNoKey = "tradeNo:" + userId + ":" + tradeNo;
        this.redisTemplate.opsForValue().setIfAbsent(tradeNoKey, tradeNo, 15, TimeUnit.MINUTES);
        orderInfoVo.setTradeNo(tradeNo);
        orderInfoVo.setPayWay("");
        orderInfoVo.setItemType(tradeVo.getItemType());
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        //时间戳 自定义
        long timestamp = SignHelper.getTimestamp();
        orderInfoVo.setTimestamp(timestamp);
        // 签名 自定义  保证订单的安全性  避免数据被修改
        //创建一个map 保存签名 map与实体类的本质是一回事
        String jsonStr = JSON.toJSONString(orderInfoVo);
        // 通过|拼接实体类的属性值 并追加一个盐 (固定的字符串)，然后再采用md5进行加密得到新的字符串
        String sign = SignHelper.getSign(JSON.parseObject(jsonStr, Map.class));
        orderInfoVo.setSign(sign);
        // 返回对象
        return orderInfoVo;
    }


    /**
     * 提交订单
     * @param orderInfoVo
     * @param userId
     * @return
     */
    @Override
    @GlobalTransactional// 全局异常处理
    public String submitOrder(OrderInfoVo orderInfoVo, Long userId) {
        //  校验签名  SignHelper.getSign(orderInfoVo --> map)
        // orderNo --->map
        Map map = JSON.parseObject(JSON.toJSONString(orderInfoVo), Map.class);
        // 进行验签 将map里面的支付方式滞空  与封装的数据要保持一致  否则就无法进行  无论怎么检验都是错
        map.put("payWay", "");
        // 校验签名
        SignHelper.checkSign(map);
        // 防止重复提交订单   获取页面流水号
        String tradeNo = orderInfoVo.getTradeNo();
        //与流水号匹配  如果匹配成功  则删除redis中的流水号  否则就返回错误信息
        String tradeNoKey = "tradeNo:" + userId + ":" + tradeNo;
//        //  判断是否存在   setIfAbsent(key,value,time,timeUnit)  不存在则能插入进去  返回true   反之为false
//        Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent(tradeNoKey, tradeNo, 15, TimeUnit.MINUTES);
//        if (!ifAbsent) {
//            // 表示重复提交订单
//            // 抛异常即可
//            throw new RuntimeException("重复提交订单");
//        }
//        // 删除缓存中的数据
//        redisTemplate.delete(tradeNoKey);
        //  2.3 比较; 或 判断key是否存在;
        //  定义lua脚本;
        String screptText = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        //  当键值与口令串一致的时候就删除数据;
        //  创建RedisScript对象;
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setResultType(Long.class);
        script.setScriptText(screptText);
        Long count = (Long) this.redisTemplate.execute(script, Arrays.asList(tradeNoKey), tradeNo);
        if (count == 0) {
            //  删除失败; 页面的值与缓存的值不相等; 重复提交了;
            throw new RuntimeException("重复提交订单");
        }
        // 下单 使用交易号作为订单流水号    或者重新生成  建议重新生成
        String orderNo = UUID.randomUUID().toString().replace("-", "");
        // 判断支付方式
        if (!SystemConstant.ORDER_PAY_ACCOUNT.equals(orderInfoVo.getPayWay())) {
            // 在线支付
            this.saveOrder(userId, orderNo, orderInfoVo);
            // 发送延迟消息 实现订单取消功能  本质就是将订单表中的状态修改成已取消
            rabbitService.sendDealyMessage(MqConst.EXCHANGE_CANCEL_ORDER, MqConst.ROUTING_CANCEL_ORDER, orderNo, MqConst.CANCEL_ORDER_DELAY_TIME);
        } else {
            // 余额支付
            //  保存订单
            this.saveOrder(userId, orderNo, orderInfoVo);
            // 锁定账户可用余额  从哪里查 查什么  账户微服务 看可用金额是否大于购买金额
            AccountDeductVo accountDeductVo = new AccountDeductVo();
            accountDeductVo.setUserId(userId);
            accountDeductVo.setAmount(orderInfoVo.getOrderAmount());
            accountDeductVo.setContent(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
            accountDeductVo.setOrderNo(orderNo);
            // 远程调用  账户微服务 锁定账户可用余额
            Result result = userAccountFeignClient.checkAndDeduct(accountDeductVo);
            if (200 != result.getCode()) {
                // 钱不够 牢底   还想买  做梦呢
                throw new RuntimeException("钱不够,别买了，充钱去吧牢底！！！");
            }
            // 扣减成功   更新订单状态
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
            orderInfo.setUpdateTime(new Date());
            // 订单状态更新
            orderInfoMapper.update(orderInfo, new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
            //  保存用户购买记录  使用远程调用  用户微服务
            // 构建实体类
            UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
            // 赋值
            userPaidRecordVo.setUserId(userId);
            userPaidRecordVo.setOrderNo(orderNo);
            // 买的什么类型  专辑 声音  还是vip
            userPaidRecordVo.setItemType(orderInfoVo.getItemType());
            // itemIdList  根据itemType  判断  专辑还是声音 东西都在哪里？   orderDetailVoList 这个集合中
            // 购买专辑  violent的话  里面只有一条  购买声音的话 里面可能是1条  也可能是多条
            List<Long> itemIdList = orderInfoVo.getOrderDetailVoList().stream().map(OrderDetailVo::getItemId).collect(Collectors.toList());
            userPaidRecordVo.setItemIdList(itemIdList);
            // 远程调用  用户微服务  保存用户购买记录  看对方需要啥  就传递啥数据
            Result userIsPaidTrack = userInfoFeignClient.savePaidRecord(userPaidRecordVo);
            // 判断用户购买记录是否保存成功
            if (200 != userIsPaidTrack.getCode()) {
                throw new RuntimeException("用户购买记录保存失败");
            }
        }
        // 数据返回
        return orderNo;
    }

    /**
     * `保存订单
     *
     * @param userId
     * @param orderNo
     * @param orderInfoVo
     */
    //  事务
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(Long userId, String orderNo, OrderInfoVo orderInfoVo) {
        //  一共需要保存那些东西  分别保存到哪？  order_info  order_detail  order_derate
        //  order_info
        OrderInfo orderInfo = new OrderInfo();
        // 属性赋值  拷贝
        BeanUtils.copyProperties(orderInfoVo, orderInfo);
        // 还缺少什么就进行赋值
        // userId
        orderInfo.setUserId(userId);
        // 订单标题
        orderInfo.setOrderTitle(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
        // 订单编号
        orderInfo.setOrderNo(orderNo);
        orderInfoMapper.insert(orderInfo);
        //  order_detail
        //  首先获取订单明细
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        //  注意 购买专辑与vip时 只有一条数据  购买声音时可能有多条 可能有一条
        if (!CollectionUtils.isEmpty(orderDetailVoList)) {
            // 循环遍历
            for (OrderDetailVo orderDetailVo : orderDetailVoList) {
                // 创建订单详情对象
                OrderDetail orderDetail = new OrderDetail();
                // 属性拷贝
                BeanUtils.copyProperties(orderDetailVo, orderDetail);
                // 缺少啥？  orderId 从哪里来  从上面保存的订单详情表中来
                orderDetail.setOrderId(orderInfo.getId());
                //  保存数据
                orderDetailMapper.insert(orderDetail);
            }
        }
        //  order_derate
        // 获取
        // 其实跟着上面的订单明细表一模一样 啊还是那个套路
        List<OrderDerateVo> orderDerateVoList = orderInfoVo.getOrderDerateVoList();
        // 循环遍历
        if (!CollectionUtils.isEmpty(orderDerateVoList)) {
            // 循环遍历
            for (OrderDerateVo orderDerateVo : orderDerateVoList) {
                // 创建订单减免对象
                OrderDerate orderDerate = new OrderDerate();
                // 属性拷贝
                BeanUtils.copyProperties(orderDerateVo, orderDerate);
                // 缺少啥？  orderId 从哪里来  从上面保存的订单详情表中来
                orderDerate.setOrderId(orderInfo.getId());
                //  保存数据
                orderDerateMapper.insert(orderDerate);
            }
        }
    }

    @Override
    public OrderInfo getOrderInfoByOrderNo(String orderNo) {
        //  查询订单主表
        OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        //  查询订单明细表
        orderInfo.setOrderDetailList(orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderInfo.getId())));
        //  返回订单明细；
        return orderInfo;
    }

    @Override
    public void orderCancel(String orderNo) {
        // 本质上就是修改订单状态
        OrderInfo orderInfo = getOrderInfoByOrderNo(orderNo);
        //  判断
        if (null != orderInfo && SystemConstant.ORDER_STATUS_UNPAID.equals(orderInfo.getOrderStatus())){
            //  赋值订单状态为已取消
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_CANCEL);
            //  更新数据
            orderInfoMapper.updateById(orderInfo);
        }
    }

    /**
     * 根据订单编号获取订单信息
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getOrderInfo(String orderNo) {
        OrderInfo orderInfo = this.getOrderInfoByOrderNo(orderNo);
        //修改支付方式
        orderInfo.setPayWayName(SystemConstant.ORDER_PAY_ACCOUNT.equals(orderInfo.getPayWay())?"余额支付":"在线支付");
        return orderInfo;
    }

    @Override
    public IPage<OrderInfo> findUserPage(Page<OrderInfo> orderInfoPage, String orderStatus, Long userId) {
        //  调用mapper 层方法
        IPage<OrderInfo> iPage = orderInfoMapper.selectUserPage(orderInfoPage, orderStatus, userId);
        iPage.getRecords().stream().forEach(orderInfo -> {
            //  赋值支付名
            orderInfo.setPayWayName(SystemConstant.ORDER_PAY_ACCOUNT.equals(orderInfo.getPayWay())?"余额支付":"在线支付");
            //  赋值支付状态名
            orderInfo.setOrderStatusName(SystemConstant.ORDER_STATUS_UNPAID.equals(orderInfo.getOrderStatus())?"未支付":SystemConstant.ORDER_STATUS_PAID.equals(orderInfo.getOrderStatus())?"已支付":"已取消");
        });
        //  返回数据；
        return iPage;
    }

    @Override
    public void orderPaySuccess(String orderNo) {
        //  修改状态为PAID;
        OrderInfo orderInfo = this.getOrderInfoByOrderNo(orderNo);
        if (null == orderInfo || SystemConstant.ORDER_STATUS_PAID.equals(orderInfo.getOrderStatus())){
            return;
        }
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
        this.updateById(orderInfo);
        //  记录用户购买记录;
        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        userPaidRecordVo.setUserId(orderInfo.getUserId());
        userPaidRecordVo.setItemType(orderInfo.getItemType());
        //  ItemId = 专辑Id; 声音Id; vipId 存储在订单明细中的itemId;
        userPaidRecordVo.setItemIdList(orderInfo.getOrderDetailList().stream().map(OrderDetail::getItemId).collect(Collectors.toList()));
        userPaidRecordVo.setOrderNo(orderNo);
        userInfoFeignClient.savePaidRecord(userPaidRecordVo);
    }
}
